import { Injectable } from '@angular/core';
import { ChartPointModel } from '../models/chartPoint.model';
import { ClusterModelWrapper } from '../../modules/research/riskCluster/cluster.model';
import { RiskListModel } from '../../modules/research/riskRating/models/riskList.model';
import { ICompany } from '../interfaces/ICompanyBase.interface';
import { CompanyModel } from '../../modules/research/company/company.model';
import { SweetAlertOptions } from 'sweetalert2';

/**
 * Utils service
 *
 * Author: Sorin Spiru
 * Date: 13.01.2018
 */
@Injectable()
export class UtilsService {
    /**
     * Checks if input string has a valid email formay
     * @param value Value to validate
     */
    public static IsValidEmail(value: string): boolean {
        var regex = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
        return value != "" && value.length > 5 && regex.test(value);
    }

    /**
     * Rounds up the input numeric value
     * @param value Input number
     */
    public static roundUp(value: number): number {
        return Math.round(value * 10) / 10;
    }

    /**
     * Generates url friendly name for a company
     * @param company Company object. Requires id and companyName fields
     */
    public static getCompanyUrlFriendlyName(company: ICompany): string {
        return this.getUrlFriendlyName(company.companyName) + '_' + company.id;
    }

    /**
     * Formats input text to be url friendly
     * @param input Text to format
     */
    public static getUrlFriendlyName(input: string): string {
        return input.replace(/[?/&=#,]/g, '-').replace(/[. ]/g, '_');
    }

    /**
     * Aggregate risk cluster
     * @param riskClusters Array of risk clusters
     * @param data Array of chart data
     * @param categoryName Category name
     */
    public static aggregateDataByRiskCluster(riskClusters: ClusterModelWrapper[], data: ChartPointModel[], categoryName: string = 'value'): Array<any> {
        return data.map((clusterData, index) => {
            // set object
            let obj = {
                riskCluster: riskClusters[index].name
            };
            obj[categoryName] = clusterData.yValue;
            return obj;
        });
    }

    /**
     * Formats a numeric value to an ordinal string value
     * @param rank Numeric rank requiring formatting
     */
    public static formatRank(rank: number): string {
        var strRank = rank.toString();
        return strRank + (strRank.endsWith("1") ? "st" :  (strRank=="12" || strRank=="13") ? "th" : (strRank.endsWith("2") ? "nd" : (strRank.endsWith("3") ? "rd" : "th")));
    }

    /**
     * Get ordinal for provided number
     * @param cardinal Number to get ordinal of
     * @param useCapital True to have the first letter capialized and false otherwise
     */
    public static getOrdinalName(cardinal: number, useCapital: boolean): string {
        var ordinals =
            [
                'zeroth',
                'first',
                'second',
                'third',
                'fourth',
                'fifth',
                'sixth',
                'seventh',
                'eighth',
                'ninth',
                'tenth',
                'eleventh',
                'twelfth',
                'thirteenth',
                'fourteenth',
                'fifteenth',
                'sixteenth',
                'seventeenth',
                'eighteenth',
                'nineteenth',
                'twentieth'
            ];

        var tens = {
            20: 'twenty',
            30: 'thirty',
            40: 'forty',
            50: 'fifty',
            60: 'sixty',
            70: 'seventy',
            80: 'eighty',
            90: 'ninety'
        };

        var ordinalTens = {
            30: 'thirtieth',
            40: 'fortieth',
            50: 'fiftieth',
            60: 'sixtieth',
            70: 'seventieth',
            80: 'eightieth',
            90: 'ninetieth',
            100: 'one hundredth',
            1000: 'one thousandth',
            1000000: 'one millionth'
        };

        var str = '';

        if (cardinal <= 20) {
            str = ordinals[cardinal];
        }
        else {
            if (cardinal % 10 === 0) {
                str = ordinalTens[cardinal];
            }
            else {
                str = tens[cardinal - (cardinal % 10)] + ordinals[cardinal % 10];
            }
        }

        if (useCapital) {
            str = str[0].toUpperCase() + str.substr(1, str.length - 1);
        }

        return str;
    }

    /**
     * Get the ordinal sufix of a number
     * @param cardinal Number to get the ordinal sufix of
     */
    public static getOrdinalNameEnd(cardinal: number): string {
        let ordinal: string = this.getOrdinalName(cardinal, false);
        return ordinal.substr(ordinal.length - 2, 2);
    }

      /**
     * Formats the input weight by multiplying it by 100
     * @param value Input numeric weight
     */
    public static formatIssueWeight(value: number): number {
        return value * 100;
    }

    public static arrayToStringWithPipes(array:string[]) : string {
        if (typeof array =="string") return array;
        if(array == null || array.length ==0) return "";
        let result = array[0];
        for(let i= 1; i<array.length; i++)
        {
            result +="|"+array[i];
        }
        return result;
    }

    public static getReportDate(): string{
        let now = new Date();
        return ('0' + now.getDate()).slice(-2) + ('0' + (1 + now.getMonth())).slice(-2) + now.getFullYear();
    }
    public static getCompanyReportName( company: CompanyModel, reportName: string, isSummary = false ): string {
        if ( isSummary ) {
            reportName = reportName + 'Summary';
        }

        // set report name
        const now = new Date();
        const nameNoGuid = company.companyNameUrlFriendly.substring(0, company.companyNameUrlFriendly.length - 37);
        const reportDate = ('0' + now.getDate()).slice(-2) + ('0' + (1 + now.getMonth())).slice(-2) + now.getFullYear();
        return `${nameNoGuid}_${reportName}_${reportDate}`;
    }

    public static mapOrder (array, order, key) {
        array.sort( function (a, b) {
          const A = a[key], B = b[key];

          if (order.indexOf(A) > order.indexOf(B)) {
            return 1;
          } else {
            return -1;
          }

        });

        return array;
    }

    public static getIconsPath() {
        return '/assets/icons-svg/';
    }

    public static getRemoteIconsPath() {
        return 'https://s3-eu-west-1.amazonaws.com/product-involvement-images/';
    }

    public static getIconFilename( iconName: string, directory = null, extension = 'svg', remote: boolean = false ) {
        return ( remote ? this.getRemoteIconsPath() : this.getIconsPath() ) + (directory ? directory + '/' : '') + iconName.replace(/\W+/g, '-') + '.' + extension;
    }

    public static getCleanIndicatorCode( code ) {
        return code ? code.split('.').join('_') : '';
    }

    public static getBaseSwalOptions(): SweetAlertOptions {
        const swalOptions: SweetAlertOptions = {
            type: undefined,
            imageClass: 'sweetalert-icon',
            buttonsStyling: false,
            customClass: 'modal-content',
            confirmButtonClass: 'btn btn-primary',
            cancelButtonClass: 'btn btn btn-outline-dark-grey mr-3',
            reverseButtons: true,
            focusCancel: false,
            focusConfirm: false,
            showCancelButton: true
        };

        return swalOptions;
    }
}
